/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ConfigSetup.java
 *
 * Created on 27/Abr/2011, 16:11:54
 */
package pt.ua.miect.sd.simuladorpesca.ui;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Logger;
import pt.ua.miect.sd.simuladorpesca.client.ClientNode;
import pt.ua.miect.sd.simuladorpesca.config.NodeService;
import pt.ua.miect.sd.simuladorpesca.config.ServiceConfig;
import pt.ua.miect.sd.simuladorpesca.config.SimulationConfig;
import pt.ua.miect.sd.simuladorpesca.server.ServerNode;

/**
 *
 * @author PedroA
 */
public class ConfigSetup extends javax.swing.JFrame {

    private ListModel<ServiceConfig> serviceModel;
    private SimulationConfig config;
    private boolean updatingFlag;

    /**
     * Creates new form ConfigSetup */
    public ConfigSetup() {
        initComponents();
        updatingFlag = true;
        serviceModel = new ListModel<ServiceConfig>();
        lstServices.setModel(serviceModel);
        txtServiceIPAddress.setInputVerifier(new RegexInputVerifier("^\\d{1,3}(\\.\\d{1,3}){3}$")); //simple regular expression to validate Ipaddress
        txtServicePort.setInputVerifier(new RegexInputVerifier("^([1-9]|[1-9]\\d+$)")); //simple regular expression to validate Ipaddress
        config = new SimulationConfig();
        loadConfig();
        setEnableState(false);
        updatingFlag = false;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        serviceGroup = new javax.swing.ButtonGroup();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        pnlConfig = new javax.swing.JPanel();
        sprCompanies = new javax.swing.JSpinner();
        jLabel3 = new javax.swing.JLabel();
        sprBoatsPerCompany = new javax.swing.JSpinner();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        sprBoatCapacity = new javax.swing.JSpinner();
        jLabel6 = new javax.swing.JLabel();
        sprFishSchools = new javax.swing.JSpinner();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel7 = new javax.swing.JLabel();
        sprFishInitialCount = new javax.swing.JSpinner();
        txtGrowthRate = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        txtEcoSystem = new javax.swing.JTextField();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel11 = new javax.swing.JLabel();
        sprMapXSize = new javax.swing.JSpinner();
        sprMapYSize = new javax.swing.JSpinner();
        jLabel12 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        lstServices = new javax.swing.JList();
        btnAddService = new javax.swing.JButton();
        btnRemoverService = new javax.swing.JButton();
        pnlService = new javax.swing.JPanel();
        txtServicePort = new javax.swing.JTextField();
        txtServiceIPAddress = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        rdbBoatService = new javax.swing.JRadioButton();
        rdbFishSchoolSerive = new javax.swing.JRadioButton();
        rdbBoatControl = new javax.swing.JRadioButton();
        rdbFishControl = new javax.swing.JRadioButton();
        rdbOperationService = new javax.swing.JRadioButton();
        rdbUI = new javax.swing.JRadioButton();
        jLabel2 = new javax.swing.JLabel();
        btnStartSimulation = new javax.swing.JButton();
        btnSaveConfig = new javax.swing.JButton();
        btnLoadConfig = new javax.swing.JButton();
        btnWaitConn = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        sprCompanies.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprCompaniesStateChanged(evt);
            }
        });

        jLabel3.setText("Companies");

        sprBoatsPerCompany.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprBoatsPerCompanyStateChanged(evt);
            }
        });

        jLabel4.setText("Boats per Company");

        jLabel5.setText("Boat Capacity");

        sprBoatCapacity.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprBoatCapacityStateChanged(evt);
            }
        });

        jLabel6.setText("Fish Schools");

        sprFishSchools.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprFishSchoolsStateChanged(evt);
            }
        });

        jLabel7.setText("Initial Count");

        sprFishInitialCount.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprFishInitialCountStateChanged(evt);
            }
        });

        txtGrowthRate.setName("txtGrowthRate"); // NOI18N
        txtGrowthRate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtGrowthRateActionPerformed(evt);
            }
        });

        jLabel8.setText("Growth Rate");

        jLabel10.setText("Eco-System Sustainability");

        txtEcoSystem.setName("txtEcoSysSust"); // NOI18N
        txtEcoSystem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtEcoSystemActionPerformed(evt);
            }
        });

        jLabel11.setText("Map X Size");

        sprMapXSize.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprMapXSizeStateChanged(evt);
            }
        });

        sprMapYSize.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sprMapYSizeStateChanged(evt);
            }
        });

        jLabel12.setText("Map Y Size");

        javax.swing.GroupLayout pnlConfigLayout = new javax.swing.GroupLayout(pnlConfig);
        pnlConfig.setLayout(pnlConfigLayout);
        pnlConfigLayout.setHorizontalGroup(
            pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlConfigLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 448, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConfigLayout.createSequentialGroup()
                        .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4)
                            .addComponent(jLabel5))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 297, Short.MAX_VALUE)
                        .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(sprBoatCapacity)
                            .addComponent(sprBoatsPerCompany)
                            .addComponent(sprCompanies, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConfigLayout.createSequentialGroup()
                        .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel6)
                            .addComponent(jLabel7))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 333, Short.MAX_VALUE)
                        .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(sprFishInitialCount)
                            .addComponent(sprFishSchools, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConfigLayout.createSequentialGroup()
                        .addComponent(jLabel8)
                        .addGap(330, 330, 330)
                        .addComponent(txtGrowthRate, 0, 0, Short.MAX_VALUE))
                    .addGroup(pnlConfigLayout.createSequentialGroup()
                        .addComponent(jLabel10)
                        .addGap(269, 269, 269)
                        .addComponent(txtEcoSystem, 0, 0, Short.MAX_VALUE))
                    .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 448, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConfigLayout.createSequentialGroup()
                        .addComponent(jLabel11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 342, Short.MAX_VALUE)
                        .addComponent(sprMapXSize, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(pnlConfigLayout.createSequentialGroup()
                        .addComponent(jLabel12)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 342, Short.MAX_VALUE)
                        .addComponent(sprMapYSize, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        pnlConfigLayout.setVerticalGroup(
            pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlConfigLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sprCompanies, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sprBoatsPerCompany, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sprBoatCapacity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(sprFishSchools, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sprFishInitialCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtGrowthRate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel10)
                    .addComponent(txtEcoSystem, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sprMapXSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel11))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sprMapYSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel12))
                .addContainerGap(20, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Configuration", pnlConfig);

        lstServices.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        lstServices.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                lstServicesValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(lstServices);

        btnAddService.setText("Add");
        btnAddService.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddServiceActionPerformed(evt);
            }
        });

        btnRemoverService.setText("Remove");
        btnRemoverService.setEnabled(false);
        btnRemoverService.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemoverServiceActionPerformed(evt);
            }
        });

        txtServicePort.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtServicePortActionPerformed(evt);
            }
        });
        txtServicePort.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtServicePortFocusLost(evt);
            }
        });

        txtServiceIPAddress.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtServiceIPAddressActionPerformed(evt);
            }
        });
        txtServiceIPAddress.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtServiceIPAddressFocusLost(evt);
            }
        });

        jLabel1.setText("IP Address");

        serviceGroup.add(rdbBoatService);
        rdbBoatService.setText("Boat Service");
        rdbBoatService.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rdbBoatServiceActionPerformed(evt);
            }
        });

        serviceGroup.add(rdbFishSchoolSerive);
        rdbFishSchoolSerive.setText("Fish Schools Service");
        rdbFishSchoolSerive.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rdbFishSchoolSeriveActionPerformed(evt);
            }
        });

        serviceGroup.add(rdbBoatControl);
        rdbBoatControl.setText("Boat Control");
        rdbBoatControl.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rdbBoatControlActionPerformed(evt);
            }
        });

        serviceGroup.add(rdbFishControl);
        rdbFishControl.setText("Fish Control");
        rdbFishControl.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rdbFishControlActionPerformed(evt);
            }
        });

        serviceGroup.add(rdbOperationService);
        rdbOperationService.setText("Operation Service");
        rdbOperationService.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rdbOperationServiceActionPerformed(evt);
            }
        });

        serviceGroup.add(rdbUI);
        rdbUI.setText("UI");
        rdbUI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rdbUIActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 133, Short.MAX_VALUE)
            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(rdbBoatService)
                        .addComponent(rdbFishSchoolSerive)
                        .addComponent(rdbBoatControl)
                        .addComponent(rdbFishControl)
                        .addComponent(rdbOperationService)
                        .addComponent(rdbUI))
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 167, Short.MAX_VALUE)
            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(rdbBoatService)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(rdbFishSchoolSerive)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(rdbBoatControl)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(rdbFishControl)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(rdbOperationService)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(rdbUI)
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        jLabel2.setText("Port");

        javax.swing.GroupLayout pnlServiceLayout = new javax.swing.GroupLayout(pnlService);
        pnlService.setLayout(pnlServiceLayout);
        pnlServiceLayout.setHorizontalGroup(
            pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 242, Short.MAX_VALUE)
            .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(pnlServiceLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGroup(pnlServiceLayout.createSequentialGroup()
                            .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel1)
                                .addComponent(jLabel2))
                            .addGap(18, 18, 18)
                            .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(txtServicePort, javax.swing.GroupLayout.DEFAULT_SIZE, 152, Short.MAX_VALUE)
                                .addComponent(txtServiceIPAddress, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addContainerGap()))
        );
        pnlServiceLayout.setVerticalGroup(
            pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 261, Short.MAX_VALUE)
            .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(pnlServiceLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(txtServiceIPAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel1))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(pnlServiceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel2)
                        .addComponent(txtServicePort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(26, Short.MAX_VALUE)))
        );

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(btnAddService, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnRemoverService)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlService, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlService, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(btnAddService)
                            .addComponent(btnRemoverService))))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Services", jPanel1);

        btnStartSimulation.setText("Start Simulation");
        btnStartSimulation.setEnabled(false);
        btnStartSimulation.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnStartSimulationActionPerformed(evt);
            }
        });

        btnSaveConfig.setText("Save Config");
        btnSaveConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveConfigActionPerformed(evt);
            }
        });

        btnLoadConfig.setText("Load Config");
        btnLoadConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadConfigActionPerformed(evt);
            }
        });

        btnWaitConn.setText("Wait Connection");
        btnWaitConn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnWaitConnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 473, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(btnLoadConfig)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnSaveConfig)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)
                        .addComponent(btnWaitConn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnStartSimulation)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnStartSimulation)
                    .addComponent(btnLoadConfig)
                    .addComponent(btnSaveConfig)
                    .addComponent(btnWaitConn))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void rdbFishSchoolSeriveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdbFishSchoolSeriveActionPerformed
        updateService(NodeService.FishSchools);
    }//GEN-LAST:event_rdbFishSchoolSeriveActionPerformed

    private void rdbBoatControlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdbBoatControlActionPerformed
        updateService(NodeService.BoatControler);
    }//GEN-LAST:event_rdbBoatControlActionPerformed

    private void rdbFishControlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdbFishControlActionPerformed
        updateService(NodeService.FishControler);
    }//GEN-LAST:event_rdbFishControlActionPerformed

    private void rdbOperationServiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdbOperationServiceActionPerformed
        updateService(NodeService.Companies);
    }//GEN-LAST:event_rdbOperationServiceActionPerformed

    private void btnAddServiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddServiceActionPerformed
        serviceModel.addElement(new ServiceConfig());
        btnStartSimulation.setEnabled(true);


    }//GEN-LAST:event_btnAddServiceActionPerformed

    /**
     * On service list ui selection
     * @param evt
     */
    private void lstServicesValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_lstServicesValueChanged
        if (updatingFlag) {
            return;// returns if the flag is active
        }
        updatingFlag = true;
        btnRemoverService.setEnabled(true);
        ServiceConfig sconf = serviceModel.getElement(lstServices.getSelectedIndex());
        if (sconf.getIpAddress() != null) {
            txtServiceIPAddress.setText(sconf.getIpAddress());
        } else {
            txtServiceIPAddress.setText("");
        }
        switch (sconf.getService()) {
            case Boats:
                rdbBoatService.setSelected(true);
                break;
            case BoatControler:
                rdbBoatControl.setSelected(true);
                break;
            case Companies:
                rdbOperationService.setSelected(true);
                break;
            case FishSchools:
                rdbFishSchoolSerive.setSelected(true);
                break;
            case FishControler:
                rdbFishControl.setSelected(true);
                break;
            case UI:
                rdbUI.setSelected(true);
                break;
        }
        txtServicePort.setText(String.valueOf(sconf.getPort()));
        setEnableState(true);
        updatingFlag = false;
    }//GEN-LAST:event_lstServicesValueChanged

    private void btnRemoverServiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoverServiceActionPerformed
        if (updatingFlag) {
            return;// returns if the flag is active
        }
        updatingFlag = true;
        int pos = lstServices.getSelectedIndex();
        if (pos != -1) {
            //lstServices.clearSelection();
            serviceModel.remove(pos);
            if (!serviceModel.isEmpty()) {
                pos--;
                if (pos < 0) {
                    lstServices.setSelectedIndex(pos + 1);
                } else {
                    lstServices.setSelectedIndex(pos);
                }
            } else {
                btnRemoverService.setEnabled(false);
                setEnableState(false);
            }
        }
        btnStartSimulation.setEnabled(serviceModel.size() > 0);
        updatingFlag = false;
    }//GEN-LAST:event_btnRemoverServiceActionPerformed

    /**
     * txtServiceIPAddress ActionPerformed
     * @param evt
     */
    private void txtServiceIPAddressActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtServiceIPAddressActionPerformed
        updateIpAddress();
    }

    /**
     * Loads the config
     */
    private void loadConfig() {
        sprBoatCapacity.setValue(config.getMaxBoatCapacity());
        sprBoatsPerCompany.setValue(config.getBoatsPerOperator());
        sprCompanies.setValue(config.getNumOperators());
        sprFishInitialCount.setValue(config.getInitialFishCount());
        sprFishSchools.setValue(config.getNumFishSchool());
        sprMapXSize.setValue(config.getMapXSize());
        sprMapYSize.setValue(config.getMapYSize());
        txtGrowthRate.setText(String.valueOf(config.getGrowthRate()));
        txtEcoSystem.setText(String.valueOf(config.getEcoCoef()));
        serviceModel.clear(); //clears model
        serviceModel.setList(config.getServices());
        btnStartSimulation.setEnabled(serviceModel.size() > 0);
    }

    /**
     * updates the IPadress of the selected service
     */
    private void updateIpAddress() {
        ServiceConfig sc = serviceModel.getElement(lstServices.getSelectedIndex());
        sc.setIpAddress(txtServiceIPAddress.getText());
        lstServices.updateUI();
    }//GEN-LAST:event_txtServiceIPAddressActionPerformed

    /**
     *  txtServiceIPAddress FocusLost event
     * @param evt
     */
    private void txtServiceIPAddressFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtServiceIPAddressFocusLost
        updateIpAddress();
    }//GEN-LAST:event_txtServiceIPAddressFocusLost

    private void txtServicePortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtServicePortActionPerformed
        updatePort();
    }//GEN-LAST:event_txtServicePortActionPerformed

    private void txtServicePortFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtServicePortFocusLost
        updatePort();
    }//GEN-LAST:event_txtServicePortFocusLost

    private void rdbUIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdbUIActionPerformed
        updateService(NodeService.UI);
    }//GEN-LAST:event_rdbUIActionPerformed

    private void rdbBoatServiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdbBoatServiceActionPerformed
        updateService(NodeService.Boats);
    }//GEN-LAST:event_rdbBoatServiceActionPerformed

    private void btnStartSimulationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartSimulationActionPerformed
        config.setServices(serviceModel.getList());
        ServerNode node = new ServerNode(config);
        node.run();
    }//GEN-LAST:event_btnStartSimulationActionPerformed

    private void sprCompaniesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprCompaniesStateChanged
        int value = (Integer) sprCompanies.getValue();
        config.setNumOperators(value);
    }//GEN-LAST:event_sprCompaniesStateChanged

    private void sprBoatsPerCompanyStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprBoatsPerCompanyStateChanged
        int value = (Integer) sprBoatsPerCompany.getValue();
        config.setBoatsPerOperator(value);
    }//GEN-LAST:event_sprBoatsPerCompanyStateChanged

    private void sprBoatCapacityStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprBoatCapacityStateChanged
        int value = (Integer) sprBoatCapacity.getValue();
        config.setMaxBoatCapacity(value);
    }//GEN-LAST:event_sprBoatCapacityStateChanged

    private void sprFishSchoolsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprFishSchoolsStateChanged
        int value = (Integer) sprFishSchools.getValue();
        config.setNumFishSchool(value);
    }//GEN-LAST:event_sprFishSchoolsStateChanged

    private void sprFishInitialCountStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprFishInitialCountStateChanged
        long value = (Long) sprFishInitialCount.getValue();
        config.setInitialFishCount(value);
    }//GEN-LAST:event_sprFishInitialCountStateChanged

    private void sprMapXSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprMapXSizeStateChanged
        int value = (Integer) sprMapXSize.getValue();
        config.setMapXSize(value);
    }//GEN-LAST:event_sprMapXSizeStateChanged

    private void sprMapYSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sprMapYSizeStateChanged
        int value = (Integer) sprMapYSize.getValue();
        config.setMapYSize(value);
    }//GEN-LAST:event_sprMapYSizeStateChanged

    private void txtGrowthRateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtGrowthRateActionPerformed
        float value = Float.parseFloat(txtGrowthRate.getText());
        config.setGrowthRate(value);
    }//GEN-LAST:event_txtGrowthRateActionPerformed

    private void txtEcoSystemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtEcoSystemActionPerformed
        float value = Float.parseFloat(txtEcoSystem.getText());
        config.setEcoCoef(value);
    }//GEN-LAST:event_txtEcoSystemActionPerformed

    /**
     * Saves config file
     * @param evt
     */
    private void btnSaveConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveConfigActionPerformed

        config.setServices(serviceModel.getList());
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Config Files", "xml");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            FileOutputStream fout = null;
            XMLEncoder encoder = null;
            try {
                fout = new FileOutputStream(chooser.getSelectedFile());
                encoder = new XMLEncoder(fout);
                encoder.writeObject(config);

            } catch (IOException ex) {
                 Logger.getRootLogger().error(ex);
            } finally {
                try {
                    encoder.close();
                    fout.close();
                } catch (IOException ex) {
                     Logger.getRootLogger().error(ex);
                }

            }

        }
    }//GEN-LAST:event_btnSaveConfigActionPerformed

    private void btnWaitConnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWaitConnActionPerformed
        String input = JOptionPane.showInputDialog(this, "Please Insert the Port", "Waiting for Connections", -1);
        try {
            int port = Integer.parseInt(input);
             ClientNode node;
            try {
                node = new ClientNode(port);
                node.run();
                
            } catch (IOException ex) {
                Logger.getRootLogger().error(ex);
            }

        } catch (NumberFormatException ex) {
            Logger.getRootLogger().error(ex);
            return;
        }
    }//GEN-LAST:event_btnWaitConnActionPerformed

    private void btnLoadConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadConfigActionPerformed
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Config Files", "xml");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            FileInputStream finput = null;
            XMLDecoder decoder = null;
            try {
                finput = new FileInputStream(chooser.getSelectedFile());
                decoder = new XMLDecoder(finput);
                config = (SimulationConfig) decoder.readObject();
                loadConfig();
            } catch (IOException ex) {
                  Logger.getRootLogger().error(ex);
            } finally {
                try {
                    decoder.close();
                    finput.close();
                } catch (IOException ex) {
                      Logger.getRootLogger().error(ex);
                }

            }

        }
    }//GEN-LAST:event_btnLoadConfigActionPerformed

    /**
     * Loads config file
     * @param evt
     */
    private void updatePort() {
        ServiceConfig sc = serviceModel.getElement(lstServices.getSelectedIndex());
        String str = txtServicePort.getText();
        int port = Integer.parseInt(str);
        sc.setPort(port);
        lstServices.updateUI();
    }

    private void updateService(NodeService service) {
        ServiceConfig sc = serviceModel.getElement(lstServices.getSelectedIndex());
        sc.setService(service);
        lstServices.updateUI();
    }

    private void setEnableState(boolean state) {
        rdbBoatControl.setEnabled(state);
        rdbBoatService.setEnabled(state);
        rdbFishControl.setEnabled(state);
        rdbFishSchoolSerive.setEnabled(state);
        rdbOperationService.setEnabled(state);
        rdbUI.setEnabled(state);
        txtServiceIPAddress.setEnabled(state);
        txtServicePort.setEnabled(state);
        if (!state) {
            txtServiceIPAddress.setText("");
            txtServicePort.setText("");
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        File logConf = new File("default-logger.properties");
        if (logConf.exists()) {
            //uses config file
            PropertyConfigurator.configure(logConf.getPath());
        } else {
            BasicConfigurator.configure();
            try {
                logConf.createNewFile(); //creats config file
                Logger.getRootLogger().info("Created config file at "+ logConf.getPath());
            } catch (IOException ex) {
                Logger.getRootLogger().error(ex);
            }
            
        }
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ConfigSetup().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAddService;
    private javax.swing.JButton btnLoadConfig;
    private javax.swing.JButton btnRemoverService;
    private javax.swing.JButton btnSaveConfig;
    private javax.swing.JButton btnStartSimulation;
    private javax.swing.JButton btnWaitConn;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JList lstServices;
    private javax.swing.JPanel pnlConfig;
    private javax.swing.JPanel pnlService;
    private javax.swing.JRadioButton rdbBoatControl;
    private javax.swing.JRadioButton rdbBoatService;
    private javax.swing.JRadioButton rdbFishControl;
    private javax.swing.JRadioButton rdbFishSchoolSerive;
    private javax.swing.JRadioButton rdbOperationService;
    private javax.swing.JRadioButton rdbUI;
    private javax.swing.ButtonGroup serviceGroup;
    private javax.swing.JSpinner sprBoatCapacity;
    private javax.swing.JSpinner sprBoatsPerCompany;
    private javax.swing.JSpinner sprCompanies;
    private javax.swing.JSpinner sprFishInitialCount;
    private javax.swing.JSpinner sprFishSchools;
    private javax.swing.JSpinner sprMapXSize;
    private javax.swing.JSpinner sprMapYSize;
    private javax.swing.JTextField txtEcoSystem;
    private javax.swing.JTextField txtGrowthRate;
    private javax.swing.JTextField txtServiceIPAddress;
    private javax.swing.JTextField txtServicePort;
    // End of variables declaration//GEN-END:variables
}
